package automaton.rule;

import automaton.view.BooleanMatrix;

public class AutomatoCelularRegraDistancia2 extends AutomatoCelularRegra {

	public AutomatoCelularRegraDistancia2(BooleanMatrix matrizTemporalAutomatos) {
		super(matrizTemporalAutomatos);
	}

	/**
	 * Regra implementada pelo proprio grupo. 
	 * Se houver numero par de vizinhos vivos entao o automato fica vivo 
	 * na proxima geracao, caso contrario morre.
	 */
	public void incrementarGeracao() {
		boolean lGeracaoAtual[] = this.getMatrizTemporalAutomatos().getLastRow(),
				lNovaGeracao[] = lGeracaoAtual.clone();
		int lContador, lContadorVizinhos, lMin, lMax, lQtdVizinho, lTempIndice;
		
		// Passando por cada um dos automatos e atualizando o resultado sendo que
		// O anterior do primeiro eh o ultimo e o proximo do ultimo eh o primeiro (circular)
		for(lContador=0;lContador < (this.getTamanhoAutomato()); lContador++)
		{
			lMin = lContador-2;
			lMax = lContador+2;
			lQtdVizinho = 0;
		  	for(lContadorVizinhos=lMin;lContadorVizinhos<lMax;lContadorVizinhos++)
		  	{
		  		if(lContadorVizinhos < 0)
		  		{
		  			lTempIndice = this.getTamanhoAutomato()+lContadorVizinhos;
		  		} else if(lContadorVizinhos >= this.getTamanhoAutomato()) {
		  			lTempIndice = this.getTamanhoAutomato()-lContadorVizinhos;
		  		} else {
		  			lTempIndice = lContadorVizinhos;
		  		}
		  		if((lTempIndice != lContador)&&(lGeracaoAtual[lTempIndice]))
		  		{
		  			lQtdVizinho++;
		  		}
		  	}

		  	lNovaGeracao[lContador] = (lQtdVizinho % 2 == 0);
		  	
		}
		try
		{
			this.getMatrizTemporalAutomatos().addRow(lNovaGeracao);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	public String toString() {
		return "Regra com distancia de vizinhanca = 2";
	}

}
